from numpy import *
from sys import *

# Loads the data from text file and return khi, a list of (x, y) tuples
def makeKhi():
	data = open("dataset.txt")
	line = data.read()
	nums = line.split()
	xlist = map(float, nums[0::2])
	ylist = map(float, nums[1::2])
	return zip(xlist, ylist)

# Returns the X matrix from a list of (x, y) tuples and an order p
def makeX(khi, p):
	X = []
	for pair in khi:
		X.append([pair[0]**i for i in range(p + 1)])
	return X

# Returns the Y matrix from a list of (x, y) tuples
def makeY(khi):
	return [pair[1] for pair in khi]

# Calculates the model g
def g(x, w):
	return sum([w[i] * x**i for i in range(len(w))])

def entrainerModele(khi, p):
	X = makeX(khi, p)
	return linalg.pinv(X).dot(makeY(khi))

def evaluerModele(w, khi):
	return mean([(pair[1] - g(pair[0], w))**2 for pair in khi])

def tache2():
	print "Tache 2\n"
	khi = makeKhi()
#	random.shuffle(khi)
	p = 3
	khiTest = khi[-20:]
	print "%s, %s, %s" % ("n", "Eemp", "Egen")
	for n in range(10, 85, 5):
		khiSel = khi[:n]
		w = entrainerModele(khiSel, p)
		Eemp = evaluerModele(w, khiSel)
		Egen = evaluerModele(w, khiTest)
		print "%d, %f, %f" % (n, Eemp, Egen)

def tache3():
	print "Tache 3\n"
	khi = makeKhi()
#	random.shuffle(khi)
	khiTrain = khi[:60]
	khiValid = khi[60:80]
	khiTest = khi[-20:]
	print "%s, %s, %s" % ("p", "Eemp", "Egen")
	Emin = 1000
	for p in range(19):
		w = entrainerModele(khiTrain, p)
		Eemp = evaluerModele(w, khiTrain)
		Egen = evaluerModele(w, khiValid)
		if Egen < Emin:
			Emin = Egen
			pstar = p
		print "%d, %f, %f" % (p, Eemp, Egen)
	print "\np*: %d\nErreur minimale: %f" % (pstar, Emin)
	w = entrainerModele(khiTrain, pstar)
	Egen = evaluerModele(w, khiTest)
	print "\nErreur obtenue avec p*: %f" % Egen

#tache2()
print
tache3()
